// vim: ft=glsl noet ts=4 sw=4 sts=0
R"vertex(
#version 330 core
smooth out vec2 uv;
smooth out vec2 dir;
smooth out vec2 cdir;   // c = corrected
smooth out vec2 cuv;    // uv <- [-0.5, +0.5] (a.k.a. centered)
smooth out vec2 cc;     // color <- [-0.5, +0.5] (a.k.a. centered)
smooth out float famount;   // flare amount
layout(location = 0) in vec2 position;
uniform vec2 center;
uniform sampler2D scene;
vec2 size;

float sample_famount(float r, float d)
{
    float rr = radians(r);
    vec2 p = vec2(cos(rr)*d, sin(rr)*d) / size;
    vec3 c = texture(scene, center + p).rgb;
    return clamp(c.r + c.g + c.b, 0.0, 1.0);
}

void main()
{
    size = textureSize(scene, 0);

    gl_Position = vec4(position, 0, 1);
    cuv = position*0.5;
    cc = center - 0.5;
    uv = cuv + 0.5;
    dir = center - uv;
    cdir = dir;

    // aspect correction
    float ac = size.x / size.y;
    cdir.x *= ac;
    cuv .x *= ac;
    cc  .x *= ac;

    // flare amount
    famount = 0;
    for (int d=10; d<40; d+=10)
        for (int r=0; r<360; r+=30)
            famount += sample_famount(r, d);
    famount = smoothstep(10, 3*12, famount);
}

)vertex"

, /////////////////////////////////////////////////////////////////////////

R"fragment(
#version 330 core
out vec3 color;
smooth in vec2 uv;
smooth in vec2 dir;
smooth in vec2 cdir;
smooth in vec2 cuv;
smooth in vec2 cc;
smooth in float famount;
uniform sampler2D scene;
uniform vec2 center;
uniform float amount;

// FIXME: unused
vec3 scatter(sampler2D s, int quality, float decay)
{
    vec3 result = vec3(0);
    for (int i=0; i<quality; i++)
        result += texture(s, uv + dir*i/quality).rgb * mix(1, float(i) / quality, decay);
    return result / quality;
}

// detail: https://www.shadertoy.com/view/XdfXRX
vec3 flare()
{
    float angle = atan(cdir.y, cdir.x);
    float glow = 1 / (length(cdir)*16.0 + 1);
    glow *= 2 + 0.1*sin(12*(angle + cc.x + cc.y));

    vec2 cuv2 = length(cuv) * cuv;
    vec3 ghost;
    ghost.r = 1 / (1 + 32*pow(length(cuv2+0.80*cc), 2)) * 0.25;
    ghost.g = 1 / (1 + 32*pow(length(cuv2+0.85*cc), 2)) * 0.23;
    ghost.b = 1 / (1 + 32*pow(length(cuv2+0.90*cc), 2)) * 0.21;

    vec2 xuv = mix(cuv, cuv2, -0.4);
    vec3 circle0;
    circle0.r = max(0, 0.01 - pow(length(xuv+0.2*cc), 5.5)) * 2;
    circle0.g = max(0, 0.01 - pow(length(xuv+0.4*cc), 5.5)) * 2;
    circle0.b = max(0, 0.01 - pow(length(xuv+0.6*cc), 5.5)) * 2;

    xuv = mix(cuv, cuv2, -0.5);
    vec3 circle1;
    circle1.r = max(0, 0.01 - pow(length(xuv+0.40*cc), 2.4)) * 6;
    circle1.g = max(0, 0.01 - pow(length(xuv+0.45*cc), 2.4)) * 5;
    circle1.b = max(0, 0.01 - pow(length(xuv+0.50*cc), 2.4)) * 3;

    xuv = mix(cuv, cuv2, -0.5);
    vec3 circle2;
    circle2.r = max(0, 0.01 - pow(length(xuv-0.30*cc), 1.6)) * 6;
    circle2.g = max(0, 0.01 - pow(length(xuv-0.32*cc), 1.6)) * 3;
    circle2.b = max(0, 0.01 - pow(length(xuv-0.35*cc), 1.6)) * 5;

    return vec3(glow) + ghost + circle0 + circle1 + circle2;
}

void main()
{
    //color = scatter(scene, 100, 0.5) * smoothstep(0, 1, amount) * flare();
    //color = scatter(scene, 100, 0.5);
    color = vec3(1.4, 1.2, 1.0) * flare() * famount;
    color *= smoothstep(0, 1, amount);
}

)fragment"

